<?php

namespace App\Service;

use App\Exception\ImageParsingError;
use Psr\Log\LoggerInterface;
use Symfony\Component\DomCrawler\Crawler;
use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
use Symfony\Contracts\HttpClient\HttpClientInterface;
use Throwable;

readonly class ImageParser implements ImageParserInterface
{
    private const IMG_SELECTOR = 'img';
    private const HTTP_METHOD_GET = 'GET';

    public function __construct(
        private HttpClientInterface $httpClient,
        private LoggerInterface $logger
    ){
    }

    /**
     * @throws ImageParsingError
     */
    public function getImageNodesByUrl(string $url): Crawler
    {
        try {
            $html = $this->getHtml($url);
            $imagesData = (new Crawler($html))->filter(self::IMG_SELECTOR);
        } catch (Throwable $e) {
            $this->logger->error(
                $e->getMessage(),
                ['exception' => $e]
            );

            throw new ImageParsingError('Ошибка получения информации об изображениях на сайте ' . $url);
        }

        if ($imagesData->count() === 0) {
            throw new ImageParsingError('На сайте ' . $url . ' нет изображений');
        }

        return $imagesData;
    }

    /**
     * @throws TransportExceptionInterface
     * @throws ServerExceptionInterface
     * @throws RedirectionExceptionInterface
     * @throws ClientExceptionInterface
     */
    private function getHtml(string $url): string
    {
        return $this->httpClient->request(self::HTTP_METHOD_GET, $url)->getContent();
    }
}
